-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix: co-int/str for CELs #5109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: co-int/str for CELs #5109
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: CEL Type Coercion Fails with `None` Values
The _coerce_eq_type_error method, intended for CEL type coercion, has multiple issues. Its get_nested helper function incorrectly attempts to access celpy activation objects as standard dictionaries, leading to None values and silent coercion failures. Additionally, the comparison logic is redundant: it always converts both values to strings for comparison, even after a specific check for mixed int/str types, rendering the initial check superfluous. Consequently, if get_nested returns None (e.g., for non-existent fields), str(None) is used in comparisons, potentially causing unintended matches with the literal string 'None'.
keep/rulesengine/rulesengine.py#L517-L549
keep/keep/rulesengine/rulesengine.py
Lines 517 to 549 in 655106f
| def get_nested(d, path): | |
| for part in path.split("."): | |
| if isinstance(d, dict): | |
| d = d.get(part) | |
| else: | |
| return None | |
| return d | |
| left_val = get_nested(activation, left) | |
| try: | |
| right_val = int(right) | |
| except Exception: | |
| try: | |
| right_val = float(right) | |
| except Exception: | |
| right_val = right | |
| # If one is str and the other is int/float, compare as str | |
| if (isinstance(left_val, (int, float)) and isinstance(right_val, str)) or ( | |
| isinstance(left_val, str) and isinstance(right_val, (int, float)) | |
| ): | |
| if op == "==": | |
| return str(left_val) == str(right_val) | |
| else: | |
| return str(left_val) != str(right_val) | |
| # Also handle both as str for robustness | |
| if op == "==": | |
| return str(left_val) == str(right_val) | |
| else: | |
| return str(left_val) != str(right_val) | |
| except Exception: | |
| pass | |
| return False |
Bug: Regex Greediness Causes Incorrect Parsing
The regex pattern r"([a-zA-Z0-9_\.]+)\s*([!=]=)\s*(.+)" used in the _coerce_eq_type_error function incorrectly parses complex CEL expressions. The greedy .+ capture group causes the right operand of a comparison (e.g., field == "value") to incorrectly include subsequent parts of the expression (e.g., "value" && other == 2). This leads to incorrect type coercion for == and != operators in such compound expressions.
keep/rulesengine/rulesengine.py#L505-L506
keep/keep/rulesengine/rulesengine.py
Lines 505 to 506 in 655106f
| m = re.match(r"([a-zA-Z0-9_\.]+)\s*([!=]=)\s*(.+)", cel) |
Was this report helpful? Give feedback by reacting with 👍 or 👎
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5109 +/- ##
===========================================
- Coverage 46.18% 30.77% -15.41%
===========================================
Files 173 100 -73
Lines 17970 11454 -6516
===========================================
- Hits 8299 3525 -4774
+ Misses 9671 7929 -1742 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
close #5107